# 遇到的

# 数组排序

注:假设有大到小

    / 冒泡排序
    // 双循环逐一比较两个元素,交换顺序
    // 时间复杂度:O(n^2),空间复杂度:O(1)
    function sort1(arr) {
        const len = arr.length
        for (let i = 0; i < len; i++) {
            for (let j = i + 1; j < len; j++) {
                if (arr[j] > arr[i]) {
                    [arr[i], arr[j]] = [arr[j], arr[i]]
                }
            }
        }
        return arr
    }
    console.log('冒泡排序', sort1([1,3,2,7,5,8,4]))

    // 插入排序
    // 类比摸扑克牌的过程,新摸到的牌比手中的大则放到前边,新摸到的比手中的小则放到后边
    // 时间复杂度:O(n^2),空间复杂度:O(n)
    function sort2(arr) {
        let hand = [arr[0]]
        let arrLen = arr.length
        for (let i = 1; i < arrLen; i++) {
            const handLen = hand.length
            if (arr[i] >= hand[handLen - 1]) {
                hand.push(arr[i])
            } else if (arr[i] <= hand[0]) {
                hand.unshift(arr[i])
            } else {
                for (let j = 0; j < handLen - 1; j++) {
                    if (arr[i] >= hand[j] && arr[i] <= hand[j + 1]) {
                        hand.splice(j + 1, 0, arr[i])
                        break
                    }
                }
            }
        }
        return hand
    }
    console.log('插入排序', sort2([2,1,4,6,8,3,2,4,6,73,2,4,6]))

    // 快速排序
    // 找到数组中间位置的元素,拿每个元素与中间元素比,大的放左边数组中,小的方右边数组中,针对新数组重复该操作
    // 时间复杂度:O(n),空间复杂度:O(n)
    function sort3(arr) {
        const len = arr.length
        if (len <= 1) {
            return arr
        }
        let middle = Math.floor(len/2)
        let mdlItm = arr[middle-1]
        arr.splice(middle-1, 1)
        const leftArr = [], rightArr = []
        for (let i = 0; i < len -1; i++) {
            if (arr[i] < mdlItm) {
                leftArr.push(arr[i])
            } else {
                rightArr.push(arr[i])
            }
        }
        return sort3(leftArr).concat(mdlItm, sort3(rightArr))
    }
    console.log('快速排序', sort3([3,12,4,6,73,5,6,3,5,72,4]))

# 数组去重

  1. Set

     function unique(arr) {
         return [...new Set(arr)]
         // return Array.from(new Set(arr))
     }
    
  2. indexOf、filter (indexOf获取元素在数组中首次出现的位置,只有唯一的元素其indexOf位置才与遍历时的index相等) O(n)

     function unique(arr) {
         return arr.filter((item, index, arr) => {
             return arr.indexOf(item) === index
         })
     }
    
  3. 检查是否重复,放入新数组

     // includes检查重复 O(n^2)
     function unique(arr) {
         let result = []
         let len = arr.length
         for (let i = 0; i < len; i++) {
             let item = arr[i]
             if (!result.includes(item)) {       // includes内部使用了while循环(其实indexOf也是这样)
                 result.push(item)
             }
         }
         return result
     }
    
     // 对象key值检查重复 O(n)
     function unique(arr) {
         let obj = {}
         let result = []
         let len = arr.length
         for (let i = 0; i < len; i++) {
             let item = arr[i]
             if (!obj[item]) {
                 result.push(item)
                 obj[item] = 1
             } else {
                 obj[item] += 1
             }
         }
         return result
     }
     // 等价于 reduce 实现 O(n)
     let hash = {}
     function unique(arr, initialVal) {
         return arr.reduce(function(previousVal, currentVal, index, array) {
             if (!hash[currentVal]) {
                 previousVal.push(currentVal)
                 hash[currentVal] = 1
             } else {
                 hash[currentVal] += 1
             }
             return previousVal
         }, initialVal)
     }
     unique(['js', 'css', 'js', 'html'], [])
    

# 数组扁平化

  1. 字符串化

利用数组的 toString 方法(或数组与字符串的隐式转化),将数组转化为字符串,再用 split 将字符串还原为数组

    function flatten(arr) {
        arr = arr.toString()    // 或者隐式转化   arr += ''
        return arr.split(',')
    }
  1. ES6 flat

     function flatten(arr) {
         return arr.flat(Infinity)
     }
    
  2. 递归

     // concat
     function flatten(arr) {
         let result = []
         let len = arr.length
         for (let i = 0; i < len; i++) {
             let item = arr[i]
             if (Array.isArray(item)) {
                 result = result.concat(flatten(item))
             } else {
                 result.push(item)
             }
         }
         return result
     }
    
     // reduce、concat
     function flatten(arr) {
         return arr.reduce((result, curItem) => {
             curItem = Array.isArray(curItem) ? flatten(curItem) : curItem
             return result.concat(curItem)
         }, [])
     }
    
     // 普通递归
     function flatten() {
         let ret = [];
         let toArr = function(arr){
             arr.forEach(function(item){
                 item instanceof Array ? toArr(item) : ret.push(item);
             });
         }
         toArr(arr);
         return ret;
     }
    
  3. 结构运算符

     function flatten(arr) {
         while (arr.some(item => Array.isArray(item))) {
             arr = [].concat(...arr)
         }
         return arr
     }
    

# 找出数组中第一个不重复的元素

    // 当前元素在去除该元素的数组中是否存在
    function getFirstUnique(arr) {
        let len = arr.length
        let target = ''
        for (let i = 0; i < len; i++) {
            let item = arr[i]
            let newArr = [].concat(arr.slice(0, i), arr.slice(i+1))
            if (!newArr.includes(item)) {
                target = item
                break
            }
        }
        return target
    }

# 找出数组中第一个不重复的元素

# 剑指offer的

# 用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。(简单)

    // 思路:栈(先进后出,数组),队列(先进先出)。从栈1取出数据放入栈2,就实现了第一个入栈1的数据,成了最后一个入栈2的数据。

    // 定义栈,并实现栈的三种方法
    function Stack() {
        var item = []
        this.push = function(node) {
            item.push(node)
        }
        this.pop = function() {
            return item.pop()
        }
        this.isEmpty = function() {
            return item.length === 0
        }
    }
    var stack1 = new Stack()
    var stack2 = new Stack()
    function push(node) {
        // write code here
        stack1.push(node)
    }
    function pop() {
        // write code here
        if (stack1.isEmpty() && stack2.isEmpty()) {
            console.log('Queue is empty')
        }
        if (stack2.isEmpty()) {
            while (!stack1.isEmpty()) {
                stack2.push(stack1.pop())
            }
        }
        console.log(stack2.pop())
    }

# 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。例如数组[3,4,5,1,2]为[1,2,3,4,5]的一个旋转,该数组的最小值为1。NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

    // 思路:首先理解“非递减排序”,是指有增有平,例如[1,2,3,3,4,5]为非递减。其次观察旋转数组[3,3,4,5,1,2]特点,旋转后非递减性被破坏了,那么比前边数字小的那个数即为最小数。
最后更新时间: 3/28/2021, 9:04:52 PM